package com.cloudsea.yunhaistores.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cloudsea.yunhaistores.entity.Spus;
import com.cloudsea.yunhaistores.mapper.SpusMapper;
import com.cloudsea.yunhaistores.service.ProductService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    private SpusMapper spusMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    // ObjectMapper用于Java对象和JSON字符串之间的转换
    @Autowired
    private ObjectMapper objectMapper;

    // 定义商品菜单在Redis中的Key前缀
    private static final String PRODUCT_LIST_KEY_PREFIX = "products:store:";
    private static final long PRODUCT_LIST_CACHE_TTL = 30; // 缓存有效期30分钟

    @Override
    public List<Spus> listProductsByStoreId(Long storeId) {
        // 1. 拼接缓存的Key
        String cacheKey = PRODUCT_LIST_KEY_PREFIX + storeId;

        // 2. 尝试从Redis中获取缓存
        String cachedProductListJson = redisTemplate.opsForValue().get(cacheKey);

        // 3. 判断缓存是否存在
        if (StringUtils.hasText(cachedProductListJson)) {
            // a. 缓存命中，将JSON字符串反序列化为List<Products>并直接返回
            try {
                return objectMapper.readValue(cachedProductListJson, new TypeReference<List<Spus>>() {});
            } catch (JsonProcessingException e) {
                // 如果反序列化失败，记录日志并继续往下走（当作缓存未命中处理）
                // log.error("Failed to deserialize product list from cache", e);
            }
        }

        // b. 缓存未命中，执行数据库查询
        QueryWrapper<Spus> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id", storeId).eq("status", 1);
        queryWrapper.orderByAsc("category").orderByDesc("created_at");
        List<Spus> productListFromDb = spusMapper.selectList(queryWrapper);

        // 4. 将从数据库中查询到的结果写入Redis缓存，并设置有效期
        try {
            String productListJson = objectMapper.writeValueAsString(productListFromDb);
            redisTemplate.opsForValue().set(cacheKey, productListJson, PRODUCT_LIST_CACHE_TTL, TimeUnit.MINUTES);
        } catch (JsonProcessingException e) {
            // 如果序列化失败，记录日志，但不影响主流程
            // log.error("无法将产品列表序列化以用于缓存", e);
        }

        // 5. 返回从数据库中获取的数据
        return productListFromDb;
    }
}
